﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Data;
using FirstFloor.ModernUI.Windows.Controls;
using MergeTool.ClassLib.Configuration;
using MergeTool.UI.Views;
using Microsoft.Practices.Prism.Commands;

namespace MergeTool.UI.ViewModels
{
    public class SetConfigBranchesViewModel : MyCustomViewModelBase
    {
        public SetConfigBranchesViewModel(TextBox approachFormTextBox)
        {
            this._mergeApproachesObservable = Settings.GetInstance().MergeApproaches;
            MergeApproaches = new ListCollectionView(_mergeApproachesObservable);
            MergeApproaches.CurrentChanged += SelectedMergeApproachChanged;
            this.BranchesObservable = (MergeApproaches.CurrentItem as MergeApproach).BranchPairs;

            this.AddApproachCommand = new DelegateCommand<object>(AddAproach);
            this.EditApproachCommand = new DelegateCommand<object>(EditApproach);
            this.RemoveApproachCommand = new DelegateCommand<object>(RemoveApproach);

            this.approachFormTextBox = approachFormTextBox;

            this.RemoveBranchCommand = new DelegateCommand<object>(RemoveBranch);
            this.MoveBranchUpCommand = new DelegateCommand<object>(MoveBranchUp);
            this.MoveBranchDownCommand = new DelegateCommand<object>(MoveBranchDown);

        }

        private void MoveBranchDown(object obj)
        {
            BranchPair br = new BranchPair
            {
                Order = SelectedBranchPair.Order-1,
                BranchNameFrom = SelectedBranchPair.BranchNameFrom,
                BranchNameTo = SelectedBranchPair.BranchNameTo,
                MergeOption = SelectedBranchPair.MergeOption,
                CheckinCommentPattern = SelectedBranchPair.CheckinCommentPattern,
                ChangesetIdToStartFrom = SelectedBranchPair.ChangesetIdToStartFrom
            };

            BranchesObservable.Remove(SelectedBranchPair);
            BranchesObservable.Add(br);
            SelectedBranchPair = br;
        }

        private void MoveBranchUp(object obj)
        {
            BranchPair br = new BranchPair
            {
                Order = SelectedBranchPair.Order + 1,
                BranchNameFrom = SelectedBranchPair.BranchNameFrom,
                BranchNameTo = SelectedBranchPair.BranchNameTo,
                MergeOption = SelectedBranchPair.MergeOption,
                CheckinCommentPattern = SelectedBranchPair.CheckinCommentPattern,
                ChangesetIdToStartFrom = SelectedBranchPair.ChangesetIdToStartFrom
            };

            BranchesObservable.Remove(SelectedBranchPair);
            BranchesObservable.Add(br);
            SelectedBranchPair = br;
        }

        private void RemoveBranch(object obj)
        {
            var branchToRemove = SelectedBranchPair;
            _branchesObservable.Remove(branchToRemove);
        }

        private void RemoveApproach(object obj)
        {
            var dialogView = new ConfirmationDialogView();
            dialogView.ActionNameTextBlock.Text = "Remove merge approach and all associated branches";
            var dlg = new ModernDialog
            {
                Title = "Confirm",
                Content = dialogView
            };
            dlg.Width = 250;
            dlg.Buttons = new Button[] { dlg.OkButton, dlg.CancelButton };
            dlg.ShowDialog();

            var dialogResult = dlg.DialogResult;
            if (dialogResult == false)
                return;
            
            MergeApproach mergeApproachToRemove =
                _mergeApproachesObservable.FirstOrDefault(ma => ma.Name.Equals(this.approachFormTextBox.Text));
            if (mergeApproachToRemove != null)
            {
                mergeApproachToRemove.BranchPairs = null;
                this.BranchesObservable = null;
                this._mergeApproachesObservable.Remove(mergeApproachToRemove);
            }
        }

        private void EditApproach(object obj)
        {
            if (!string.IsNullOrEmpty(this.approachFormTextBox.Text))
            {
                BindingExpression be = this.approachFormTextBox.GetBindingExpression(TextBox.TextProperty);
                be.UpdateSource();
            }
        }

        private void AddAproach(object obj)
        {
            if (!string.IsNullOrEmpty(this.approachFormTextBox.Text))
            {
                var newMergeApproach = new MergeApproach()
                {
                    Name = this.approachFormTextBox.Text
                };
                this.BranchesObservable = new ObservableCollection<BranchPair>();
                newMergeApproach.BranchPairs = BranchesObservable;
                this._mergeApproachesObservable.Add(newMergeApproach);
                this.MergeApproaches.MoveCurrentTo((object)newMergeApproach);
            }
        }


        public DelegateCommand<object> AddApproachCommand { get; private set; }
        public DelegateCommand<object> EditApproachCommand { get; private set; }
        public DelegateCommand<object> RemoveApproachCommand { get; private set; }

        public DelegateCommand<object> RemoveBranchCommand { get; private set; }
        public DelegateCommand<object> MoveBranchUpCommand { get; private set; }
        public DelegateCommand<object> MoveBranchDownCommand { get; private set; }

        public ICollectionView MergeApproaches { get; set; }

        private ObservableCollection<MergeApproach> _mergeApproachesObservable;

        public MergeApproach SelectedMergeApproach
        {
            get
            {
                return _selectedMergeApproach;
            }
            set
            {
                SetProperty(ref _selectedMergeApproach, value);
                this._selectedMergeApproach = value;
            }
        }

        private MergeApproach _selectedMergeApproach;
        
        
        private void SelectedMergeApproachChanged(object sender, EventArgs e)
        {
            this.SelectedMergeApproach = MergeApproaches.CurrentItem as MergeApproach;

            if (SelectedMergeApproach != null)
            {
                this.BranchesObservable = SelectedMergeApproach.BranchPairs;
            }
            else
            {
                this.BranchesObservable = null;
            }
        }

        public BranchPair SelectedBranchPair
        {
            get
            {
                return this._selectedBranchPair;
            }

            set
            {
                SetProperty(ref _selectedBranchPair, value);
                this._selectedBranchPair = value;
            }
        }

        private BranchPair _selectedBranchPair;
        

        public ObservableCollection<BranchPair> BranchesObservable
        {
            get
            {
                return this._branchesObservable;
            }
            set
            {
                SetProperty(ref _branchesObservable, value);
                this._branchesObservable = value;
            }
        }

        private ObservableCollection<BranchPair> _branchesObservable;
        private TextBox approachFormTextBox;
    }
}
